﻿Imports System
Imports System.CodeDom
Imports System.Reflection

Namespace System.Workflow.ComponentModel.Compiler
    Friend NotInheritable Class DesignTimeEventInfo
        Inherits EventInfo
        ' Methods
        Friend Sub New(ByVal declaringType As DesignTimeType, ByVal codeDomEvent As CodeMemberEvent)
            If (declaringType Is Nothing) Then
                Throw New ArgumentNullException("Declaring Type")
            End If
            If (codeDomEvent Is Nothing) Then
                Throw New ArgumentNullException("codeDomEvent")
            End If
            Me.declaringType = declaringType
            Me.codeDomEvent = codeDomEvent
            Me.name = Helper.EnsureTypeName(codeDomEvent.Name)
            Me.memberAttributes = codeDomEvent.Attributes
            Me.addMethod = Nothing
            Me.removeMethod = Nothing
        End Sub

        Public Overrides Function GetAddMethod(ByVal nonPublic As Boolean) As MethodInfo
            If ((Me.addMethod Is Nothing) AndAlso (Not Me.declaringType.ResolveType(DesignTimeType.GetTypeNameFromCodeTypeReference(Me.codeDomEvent.Type, Me.declaringType)) Is Nothing)) Then
                Dim methodInfo As New CodeMemberMethod { _
                    .Name = ("add_" & Me.name), _
                    .ReturnType = New CodeTypeReference(GetType(Void)) _
                }
                methodInfo.Parameters.Add(New CodeParameterDeclarationExpression(Me.codeDomEvent.Type, "Handler"))
                methodInfo.Attributes = Me.memberAttributes
                Me.addMethod = New DesignTimeMethodInfo(Me.declaringType, methodInfo, True)
            End If
            Return Me.addMethod
        End Function

        Public Overrides Function GetCustomAttributes(ByVal inherit As Boolean) As Object()
            Return Me.GetCustomAttributes(GetType(Object), inherit)
        End Function

        Public Overrides Function GetCustomAttributes(ByVal attributeType As Type, ByVal inherit As Boolean) As Object()
            If (attributeType Is Nothing) Then
                Throw New ArgumentNullException("attributeType")
            End If
            If (Me.attributes Is Nothing) Then
                Me.attributes = Helper.LoadCustomAttributes(Me.codeDomEvent.CustomAttributes, [TryCast](Me.DeclaringType,DesignTimeType))
            End If
            Return Helper.GetCustomAttributes(attributeType, inherit, Me.attributes, Me)
        End Function

        Public Overrides Function GetRaiseMethod(ByVal nonPublic As Boolean) As MethodInfo
            Return Nothing
        End Function

        Public Overrides Function GetRemoveMethod(ByVal nonPublic As Boolean) As MethodInfo
            If (Me.removeMethod Is Nothing) Then
                Dim type As Type = Me.declaringType.ResolveType(DesignTimeType.GetTypeNameFromCodeTypeReference(Me.codeDomEvent.Type, Me.declaringType))
                If (Not type Is Nothing) Then
                    Dim methodInfo As New CodeMemberMethod { _
                        .Name = ("remove_" & Me.name), _
                        .ReturnType = New CodeTypeReference(GetType(Void)) _
                    }
                    methodInfo.Parameters.Add(New CodeParameterDeclarationExpression(type, "Handler"))
                    methodInfo.Attributes = Me.memberAttributes
                    Me.removeMethod = New DesignTimeMethodInfo(Me.declaringType, methodInfo, True)
                End If
            End If
            Return Me.removeMethod
        End Function

        Public Overrides Function IsDefined(ByVal attributeType As Type, ByVal inherit As Boolean) As Boolean
            If (attributeType Is Nothing) Then
                Throw New ArgumentNullException("attributeType")
            End If
            If (Me.attributes Is Nothing) Then
                Me.attributes = Helper.LoadCustomAttributes(Me.codeDomEvent.CustomAttributes, [TryCast](Me.DeclaringType,DesignTimeType))
            End If
            Return Helper.IsDefined(attributeType, inherit, Me.attributes, Me)
        End Function


        ' Properties
        Public Overrides ReadOnly Property Attributes As EventAttributes
            Get
                Return EventAttributes.None
            End Get
        End Property

        Public Overrides ReadOnly Property DeclaringType As Type
            Get
                Return Me.declaringType
            End Get
        End Property

        Friend ReadOnly Property IsPublic As Boolean
            Get
                Return ((Me.memberAttributes And MemberAttributes.Public) <> DirectCast(0, MemberAttributes))
            End Get
        End Property

        Friend ReadOnly Property IsStatic As Boolean
            Get
                Return ((Me.memberAttributes And MemberAttributes.Static) <> DirectCast(0, MemberAttributes))
            End Get
        End Property

        Public Overrides ReadOnly Property Name As String
            Get
                Return Me.name
            End Get
        End Property

        Public Overrides ReadOnly Property ReflectedType As Type
            Get
                Return Me.declaringType
            End Get
        End Property


        ' Fields
        Private addMethod As DesignTimeMethodInfo
        Private attributes As Attribute()
        Private codeDomEvent As CodeMemberEvent
        Private declaringType As DesignTimeType
        Private memberAttributes As MemberAttributes
        Private name As String
        Private removeMethod As DesignTimeMethodInfo
    End Class
End Namespace

